<?php

/*
	Class: BlogPosts

	About: Author
		Jaybill McCarthy

	About: License
		<http://communit.as/docs/license>
*/
class BlogPosts extends Blog_Db_Table {

	protected $_name = 'blog_posts';

	protected $_primary = 'id';

	function fetchByAuthorUsername($username) {
		$posts = $this->fetchAll($this->select()->where('author_username = ?', $username));
		return $posts;		
	}

	function fetchByMonth($month, $year, $tags = null) {
		$posts = $this->fetchAll($this->select()
			->where($this->getMonthWhereClause($month, $year, $tags)));
		return $posts;		
	}
	
	function getMonthsWithPosts($tags = null,$show_empty = true,$only_current_year = false) {
				
		$current_month 	= date("n");
		$current_year 	= date("Y");	


		if($only_current_year) {
			$earliest_year = $current_year;
			$earliest_month = 1;
		}else{	
			$posts = $this->fetchAllActive("publish_on",1);
					
			if(!is_null($posts)) {
				$posts = $posts->toArray();
				$first_post = $posts[0];
				
				$earliest_month 	= date("n",strtotime($first_post['publish_on']));
				$earliest_year 		= date("Y",strtotime($first_post['publish_on']));			
			}
		}	
		$archives = array();
		
		for($year = $current_year; $year >= $earliest_year; $year = $year - 1) {
			for($month = 12; $month > 0;$month = $month - 1) {
				if(($year == $current_year and $month <= $current_month) or $year < $current_year) {
					if(($year >= $earliest_year and $month >= $earliest_month) or $year > $earliest_year) { 
					$posts_in_month = $this->getCountByWhereClause($this->getMonthWhereClause($month,$year,$tags));					
						if($posts_in_month > 0 or $show_empty) {
							$archives[$year][$month] = $posts_in_month;
						}
					}
				}
			}
		}
		
		
		return($archives);	
	}

	function getMonthWhereClause($month,$year,$tags = null) {
		
		$month_start_timestamp = mktime(0,0,0,$month,1,$year);
								
		$end_year = $year;		
		
		if($month == 12) {
			$end_year = $year + 1;
			$end_month = 1;
		} else {
			$end_month = $month + 1;
			
		}
		
		$month_end_timestamp = mktime(0,0,0,$end_month,1,$end_year) - 1;
		
		if($month_end_timestamp > time()){
			$month_end_timestamp = time();
		}
		
		$select = $this->select();
		
		if(!is_null($tags)) {
			$select->where($this->getTagWhereClause($tags));
		}
		
		$select->where("UNIX_TIMESTAMP(publish_on) > ? ", $month_start_timestamp)
				->where("UNIX_TIMESTAMP(publish_on) < ? ", $month_end_timestamp)
				->where("active = 1");
		$month_where = implode($select->getPart("where"));
						
		return($month_where);
		
	}
	
	/*
		Function: setMetaData
			Updates the metadata object for a post.

		Arguments:
			id - username that will have thier metadata updated
			key - the field name of the metadata field
			value - the metadata value to be set 
	*/
	function setMetaData($id, $key, $value) {
		$post = $this->fetchRow($this->select()->where("id = ?",$id));
		if (!is_null($post)) {
			if (!is_null($post->metadata)) {
				$metadata = unserialize($post->metadata);
			} else {
				$metadata = array();
			}
			$metadata[$key] = $value;
			$post->metadata = serialize($metadata);
			$post->save();
		}
	}
	
	/*
		Function: getMetaData
			Returns either a value or an array of metadata values for a post.

		Arguments:
			id - username that will have thier metadata updated
			key (optional)- the field name of the metadata field. If this isn't specifed, an associative array with all values is returned.			 
	*/
	function getMetaData($id, $key = null) {
		$post = $this->fetchRow($this->select()->where("id = ?",$id));
		$out = null;
		if (!is_null($post)) {
			if (!is_null($post->metadata)) {
				$metadata = unserialize($post->metadata);
				if (is_null($key)) {
						$out = $metadata;
				} else {
					if (array_key_exists($key,$metadata)) {
						$out = $metadata[$key];	
					}					
				}  
			}
		}
		return $out;
	}	
	
	function fetchBySlug($slug, $showInactive = false) {
		$select = $this->select();		
		$select->where("slug = ?",$slug);
		if(!$showInactive) {
			$select->where("active = ?",1);	
		}		
		
		return $this->fetchRow($select);
	}
	
	function fetchById($id, $showInactive = false) {
		$select = $this->select();		
		$select->where("id = ?",$id);
		if(!$showInactive) {
			$select->where("active = 1");	
		}		
		return $this->fetchRow($select);
	}
	
	function slugExists($slug) {
		$out = false;
		if($this->getCountByWhereClause($this->getAdapter()->quoteInto("slug = ?",$slug)) > 0) {
			$out = true;
		}
		
		return $out;
	}
	
	function getTagsById($id) {
		$out = null;
		
		$post = $this->fetchRow($this->select()->where("id = ?",$id));
		
		if(!is_null($post)) {
			$out = unserialize($post->tags);
			if($out === false) {
				$out = array();
			}	
		}
		
		return $out;
	}
	
	function getIdBySlug($slug) {
		$post = $this->fetchRow($this->select()->where("slug = ?", $slug));		
		if(!is_null($post)) {
			return $post->id;
		} else {
			return null;
		}
	}
	
	function fetchSimilarById($id, $showInactive = false, $count = null, $offset = null) {

		$select = $this->select();		
		$tag_array = $this->getTagsById($id);
		if(count($tag_array) > 0) {
			$select->where($this->getTagWhereClause($tag_array));
		}
								
		if(!$showInactive) {
			$select->where("active = 1");
			$select->where("unix_timestamp(publish_on) < unix_timestamp(now())");	
		}
				
		$select->where("id <> ?", $id);	
		$select->order(array("publish_on desc"));
		$select->limit($count,$offset);
		return $this->fetchAll($select, "publish_on desc", $count, $offset);
		
	}
	
	function fetchAllActive($order = null, $count = null, $offset = null) {		

		$select = $this->select()
			->where("active = 1")
			->where("unix_timestamp(publish_on) < unix_timestamp(now())")
			->order($order);
			
			if(!is_null($count)) {
				if(is_null($offset)) {
					$offset = 0;
				}
				$select->limit($count,$offset);
			}
			
			//dd($select->assemble());
		return $this->fetchAll($select);
		
	}

	function getTagWhereClause($tags, $mode = "any") {
		if(!is_array($tags)) {
			$tags = array($tags);
		}		
		$select = $this->select();
		foreach($tags as $tag) {
			if($mode == "any") {
				$select->orWhere('tags like ?', '%"' . $tag . '"%');
			} elseif ($mode == "all") {
				$select->where('tags like ?', '%"' . $tag . '"%');
			}
		}
		return implode(" ", $select->getPart("where"));
	}

	function getKeywordsWhereClause($keywords, $mode = "any") {
		if(!is_array($keywords)) {
			$keywords = explode(" ", $keywords);
		}		
		$select = $this->select();
		foreach($keywords as $keyword) {
			if($mode == "any") {
				$select->orWhere('title like ?', '%' . $keyword . '%');
				$select->orWhere('slug like ?', '%' . $keyword . '%');
				$select->orWhere('body like ?', '%' . $keyword . '%');
				$select->orWhere('tags like ?', '%"' . $keyword . '"%');
			} elseif ($mode == "all") {
				$select->where('title like ?', '%' . $keyword . '%');
				$select->where('slug like ?', '%' . $keyword . '%');
				$select->where('body like ?', '%' . $keyword . '%');
				$select->where('tags like ?', '%"' . $keyword . '"%');
			}
		}
		return implode(" ", $select->getPart("where"));
	}

	function fetchAllByTags($tags, $showInactive = false, $count = null, $offset = null, $mode = "any",$exclude_ids = null) {
		$select = $this->select();		
		$select->where($this->getTagWhereClause($tags, $mode));
		if(!$showInactive) {
			$select->where("active = 1");
			$select->where("unix_timestamp(publish_on) < unix_timestamp(now())");	
		}
		if(is_array($exclude_ids)){
			foreach($exclude_ids as $exclude_id){
				$select->where('id <> ?',$exclude_id);
			}
		}
		$select->order(array("publish_on desc"));
		$select->limit($count,$offset);
		return $this->fetchAll($select);
	}

	function fetchAllByKeywords($keywords, $showInactive = false, $count = null, $offset = null, $mode = "any") {
		$select = $this->select();
		$select->where($this->getKeywordsWhereClause($keywords, $mode));
		if(!$showInactive) {
			$select->where("active = 1");
			$select->where("unix_timestamp(publish_on) < unix_timestamp(now())");
		}
		$select->order(array("publish_on desc"));
		
		return $this->fetchAll($select,null, $count, $offset);
	}

	function getThumbnailUrl($post_id, $width) {
		$where = $this->getAdapter()->quoteInto("id = ?", $post_id);
		$tmp_post = $this->fetchRowArray($where);
		$metadata = unserialize($tmp_post['metadata']);
		$media_table = new BlogMedia();
		$where = $media_table->getAdapter()->quoteInto("id = ?", $metadata['thumbnail_media_id']);
		$thumbnail_row = $media_table->fetchRowArray($where);
		return "/blogimages/post-".$post_id."/".$width."/1/".$thumbnail_row['filename'];
	}

	function fetchAllByCategorySlugs($slugs, $showInactive = false, $count = null, $offset = null) {
		
		$categories_table = new BlogCategories();

		// get array of ids for slugs
		if(!is_array($slugs)) {
			$slugs = array($slugs);
		}
		
		$category_select = $categories_table->select();
		foreach($slugs as $slug) {			
			$category_select->orWhere("category_id = ?", $categories_table->getCategoryIdBySlug($slug));
		}

		$category_where = implode($category_select->getPart("where"));

		$select = $this->select();
		$select->where("id in (select post_id from blog_post_category where ".$category_where.")");
		
		if(!$showInactive) {
			$select->where("active = 1");
			$select->where("unix_timestamp(publish_on) < unix_timestamp(now())");	
		}	
		
		return $this->fetchAll($select, "publish_on desc", $count, $offset);

	}	
	
	function addTag($id, $tag) {
		
		$post = $this->fetchById($id,true);
		
		if(!is_null($post)) {
			$tags = unserialize($post->tags);
			if(is_array($tags)) {
				$tags[] = $tag;
			} else {
				$tags = array($tag);
			}
			
			$post->tags = serialize($tags);			
			$post->save();			
		}
		
	}
	
	function prepareRowsetForView($post_rowset) {
		$tmp_posts = array();
		foreach($post_rowset as $post) {			
			$tmp_posts[] = $this->preparePostForView($post);
		}
		return $tmp_posts;
	}

	function preparePostForView($post) {

		$users_table = new Users();
		$media_table = new BlogMedia();
		$tmp_post = $post->toArray();
		$tmp_post['title'] = stripslashes($tmp_post['title']);
		$tmp_post['body'] = stripslashes($tmp_post['body']);
		$author = $users_table->fetchByUsername($tmp_post['author_username']);

		if (!is_null($author)) {
			$tmp_post['author'] = $author->toArray();					
		}

		$tmp_post['tags'] = unserialize($tmp_post['tags']);

		if (!is_array($tmp_post['tags'])) {
			$tmp_post['tags'] = array();
		}

		$media = $media_table->fetchAll($media_table->select()->where("post_id = ? and is_finalized=1 and active = 1", $tmp_post['id']));
		if (!is_null($media)) {
			$tmp_post['media'] = $media->toArray();
		}
		$tmp_post['metadata'] = $this->getMetaData($tmp_post['id']);

		$posts_categories_table = new BlogPostsCategories();
		$categories_table = new BlogCategories();
		$posts_categories = $posts_categories_table->fetchAll($posts_categories_table->select()->where('post_id = ?', $tmp_post['id']));
		if (count($posts_categories) > 0) {
			foreach ($posts_categories as $post_category) {
				$category = $categories_table->fetchRow($categories_table->select()->where('id = ?', $post_category->category_id));
				if (!is_null($category)) {
					$category = $category->toArray();
					$tmp_post['categories'][] = $category;
					if(array_key_exists('category_slug',$category)){
						$cat_slug_split = explode("-", $category['category_slug']);
						
						if(count($cat_slug_split) > 1){
							$tmp_post['filed_under'][$cat_slug_split[0]] = $cat_slug_split[1];
						}
					}
				}
			} 	
		}

		return $tmp_post;
	}
	
	function delete($where) {		
		$posts = $this->fetchAll($where);
		$modules_table = new Modules();
		$a = $this->getAdapter();
		if(count($posts) > 0) {
			$states_content_table = new WorkflowStatesContent();
			foreach($posts as $post) {
				
				// delete workflow state
				if($modules_table->isEnabled("workflow")){
					$state_where = $a->quoteInto("contenttype_id = 'blog' and content_id = ?",$post->id);
					$states_content_table->delete($state_where);
				}
				
				// delete comments
				$comments_table = new BlogComments();
				$comments_where = $a->quoteInto("post_id = ?",$post->id);
				$comments_table->delete($comments_where);
				
				// delete categories
				$categories_table = new BlogPostsCategories();
				$categories_where = $a->quoteInto("post_id = ?",$post->id);
				$categories_table->delete($categories_where);
				
				// delete media 
				$media_path = Zend_Registry::get('basepath'). "/uploads/blog/post-".$post->id;
				Cts_Filesystem::SureRemoveDir($media_path,true);
				$media_table = new BlogMedia();
				$media_where = $a->quoteInto("post_id = ?",$post->id);
				$media_table->delete($media_where);
				
			}			
		}				
		return parent::delete($where);
	}	

	function unpublishBulk($ids) {
		$where = "id in ('0'";
		foreach ($ids as $id) {
			$where .= ", ".$id;
		}
		$where .= ")";
		// $where should end up looking like this:
		// id in (0, 4, 23, 6, 324)
		$data = array('active' => "0");
		$rowsupdated = $this->update($data, $where);
		if ($rowsupdated >= 1) {
			return true;
		} else {
			return false;
		}
	}

	// TODO - this should be in cts db table abstract
	function getBulk(array $ids) {
		$where = "id in (0";
		foreach ($ids as $id) {
			$where .= ", ".$id;
		}
		$where .= ")";
		// $where should end up looking like this:
		// id in (0, 4, 23, 6, 324)
		$tmp_rows = $this->fetchAll($where);
		if (!is_null($tmp_rows)) {
			return $tmp_rows->toArray();
		} else {
			return array();
		}
	}

	function getEarliestCreateDate() {
		$total = $this->getCountByWhereClause();
		if($total > 0){		
			$post = $this->fetchAllArray(null, "created_on asc", 1);
			return $post[0]['created_on'];
		} else {
			return null;
		}
	}

	function getLatestCreateDate() {
		$total = $this->getCountByWhereClause();
		if($total > 0){		
			$post = $this->fetchAllArray(null, "created_on desc", 1);
			return $post[0]['created_on'];
		} else {
			return null;
		}
	}

	function timeFrameHasPosts($start_date = null, $end_date = null) {
		if (is_null($start_date)) {
			$start_date = date("Y-m-d", 0);
		} else {
			$start_date = date("Y-m-d", strtotime($start_date));
		}
		if (is_null($end_date)) {
			$end_date = date("Y-m-d", strtotime("2038-01-18"));
		} else {
			$end_date = date("Y-m-d", strtotime($end_date));
		}
		if ($this->getCountByWhereClause("created_on between '".$start_date."' and '".$end_date."'") >= 1) {
			return true;
		} else {
			return false;
		}
	}

}
